//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Segmento.h"
//----------------------------Private Stuff!---------------------------------
//---------------------------------------------------------------------------
int Segmento::asignaCodigo(PV2D* punto, GLdouble wl, GLdouble wt,
        GLdouble wr, GLdouble wb){
        int cod=0;

        //frontera izk TFFF
        if(punto->getX()<wl){
                cod|=8;
        }
        //frontera arriba
        if(punto->getY()>wt){
                cod|=4;
        }
        //frontera drch
        if(punto->getX()>wr){
                cod|=2;
        }
        //frontera abajo
        if(punto->getY()<wb){
                cod|=1;
        }

        return cod;
}
//---------------------------------------------------------------------------
//----------------------------Public Stuff!----------------------------------
Segmento::Segmento(){
        _inicioSegmento=NULL;
        _finSegmento=NULL;
        _normal=NULL;
}
//---------------------------------------------------------------------------
Segmento::Segmento(PV2D* principio, PV2D* final){
        _inicioSegmento=principio;
        _finSegmento=final;
        /*
        GLdouble x = final->getX()-principio->getX();
        GLdouble y = final->getY()-principio->getY();*/
        GLdouble x = principio->getX()-final->getX();
        GLdouble y = principio->getY()-final->getY();
        //Normalizamos
        GLdouble x2 = x*x;
        GLdouble y2 = y*y;
        GLdouble modulo = sqrt(x2+y2);
        x=x/modulo;
        y=y/modulo;
        /*         x        -y
                v= y  => n=  x
                   0         0
        */
        _normal=new PV2D(-y,x,0);
}
//---------------------------------------------------------------------------
Segmento::Segmento(GLdouble xIni, GLdouble yIni, GLdouble xFin, GLdouble yFin){
        _inicioSegmento=new PV2D(xIni,yIni,1);
        _finSegmento=new PV2D(xFin,yFin,1);

        GLdouble x = xFin-xIni;
        GLdouble y = yFin-yIni;
        //Normalizamos
        GLdouble x2 = x*x;
        GLdouble y2 = y*y;
        GLdouble modulo = sqrt(x2+y2);
        x=x/modulo;
        y=y/modulo;
        /*         x        -y
                v= y  => n=  x
                   0         0
        */
        _normal=new PV2D(-y,x,0);
}
//---------------------------------------------------------------------------
Segmento::~Segmento(){
        if(_inicioSegmento!=NULL){
                delete _inicioSegmento;
                _inicioSegmento=NULL;
        }
        if(_finSegmento!=NULL){
                delete _finSegmento;
                _finSegmento=NULL;
        }
        if(_normal!=NULL){
                delete _normal;
                _normal=NULL;
        }
}
//---------------------------------------------------------------------------
Segmento* Segmento::clone(){
        return new Segmento(_inicioSegmento->clone(),_finSegmento->clone());
}
//---------------------------------------------------------------------------
AnsiString Segmento::toXM(){
        AnsiString out="<SEGMENTO>\n";
        out+="<INICIO>\n<CORX>"+AnsiString(_inicioSegmento->getX())+"</CORX>\n";
        out+="<CORY>"+AnsiString(_inicioSegmento->getY())+"</CORY>\n</INICIO>\n";
        out+="<FIN>\n<CORX>"+AnsiString(_finSegmento->getX())+"</CORX>\n";
        out+="<CORY>"+AnsiString(_finSegmento->getY())+"</CORY>\n</FIN>\n";
        out+="</SEGMENTO>\n";
        return out;
}
//---------------------------------------------------------------------------
Segmento* Segmento::fromXM(XM* xm){
        PV2D* ini,*fin;
        double x,y;
        x=xm->getAttribute("INICIO")->getAttribute("CORX")->getDouble();
        y=xm->getAttribute("INICIO")->getAttribute("CORY")->getDouble();
        ini=new PV2D(x,y,1);
        x=xm->getAttribute("FIN")->getAttribute("CORX")->getDouble();
        y=xm->getAttribute("FIN")->getAttribute("CORY")->getDouble();
        fin=new PV2D(x,y,1);

        return new Segmento(ini,fin);
}
//---------------------------------------------------------------------------
bool Segmento::cohen_sutherland(GLdouble xRec,GLdouble yRec,
        GLdouble xprimaRec,GLdouble yprimaRec){
        GLdouble wl,wt,wr,wb,d;
        if(xRec<xprimaRec){
                wl=xRec;
                wr=xprimaRec;
        }else{
                wl=xprimaRec;
                wr=xRec;
        }
        if(yRec>yprimaRec){
                wt=yRec;
                wb=yprimaRec;
        }else{
                wt=yprimaRec;
                wb=yRec;
        }
        int codP1 = asignaCodigo(_inicioSegmento,wl,wt,wr,wb);
        int codP2 = asignaCodigo(_finSegmento,wl,wt,wr,wb);
        /*
                Rechazo trivial
        */
        if((codP1 & codP2)!=0){
                return false;
        }
        /*
                Exito trivial
        */
        if((codP1 | codP2)==0){
                return true;
        }
        /*
                Ajusto Segmento
        */

        //Frontera Izk
        /*
                d/x1-L = y1-y2 / x2 - x1
        */
        if(codP1==8 || codP1 == 12 || codP1 == 9){/*
                if(_inicioSegmento->getY()>_finSegmento->getY()){
                     d=((_inicioSegmento->getY() - _finSegmento->getY())
                                /(_finSegmento->getX()- _inicioSegmento->getX()))
                                        *(_inicioSegmento->getX() - wl);
                     _inicioSegmento->mueve(wl,_inicioSegmento->getY()-d);

                }else{
                        d=((_finSegmento->getY()-_inicioSegmento->getY())
                                /(_finSegmento->getX() - _inicioSegmento->getX()))
                                        *(_inicioSegmento->getX() - wl);
                        _inicioSegmento->mueve(wl,_inicioSegmento->getY()+d);
                } */

                d=((_inicioSegmento->getY() - _finSegmento->getY())
                                /(_finSegmento->getX()- _inicioSegmento->getX()))
                                        *(_inicioSegmento->getX() - wl);
                     _inicioSegmento->mueve(wl,_inicioSegmento->getY()+d);
        }
        /*
                d/x2-L = y2-y1 / x1 - x2
        */
        if(codP2==8 || codP2 == 12 || codP2 == 9){/*
                if(_finSegmento->getY()>_inicioSegmento->getY()){

                        d=((_finSegmento->getY() -  _inicioSegmento->getY())
                                /(_inicioSegmento->getX() - _finSegmento->getX()))
                                        *(_finSegmento->getX() - wl);
                        _finSegmento->mueve(wl,_finSegmento->getY()-d);
                }else{
                        d=((_inicioSegmento->getY() - _finSegmento->getY())
                                /(_inicioSegmento->getX() - _finSegmento->getX()))
                                        *(_finSegmento->getX() - wl);
                        _finSegmento->mueve(wl, _finSegmento->getY()+d);
                }*/
                d=((_finSegmento->getY() -  _inicioSegmento->getY())
                                /(_inicioSegmento->getX() - _finSegmento->getX()))
                                        *(_finSegmento->getX() - wl);
                        _finSegmento->mueve(wl,_finSegmento->getY()+d);
        }
        //Frontera Arriba
        /*
                d/y1-T = x2 - x1 / y1 - y2
        */
        if(codP1==12 || codP1==4 || codP1==6){/*
                if(_inicioSegmento->getX()<_finSegmento->getX()){

                        d=((_finSegmento->getX() - _inicioSegmento->getX())
                                /(_inicioSegmento->getY() - _finSegmento->getY()))
                                        *(_inicioSegmento->getY() - wt);
                        _inicioSegmento->mueve(_inicioSegmento->getX()+d,wt);
                }else{
                        d=((_inicioSegmento->getX() - _finSegmento->getX())
                                /(_inicioSegmento->getY() - _finSegmento->getY()))
                                        *(_inicioSegmento->getY() - wt);
                        _inicioSegmento->mueve(_inicioSegmento->getX()-d,wt);
                }*/
                d=((_finSegmento->getX() - _inicioSegmento->getX())
                                /(_inicioSegmento->getY() - _finSegmento->getY()))
                                        *(_inicioSegmento->getY() - wt);
                        _inicioSegmento->mueve(_inicioSegmento->getX()+d,wt);
        }
        /*
                d/y2-T = x1 - x2 / y2 - y1
        */
        if(codP2==12 || codP2==4 || codP2==6){/*
                if(_finSegmento->getX() < _inicioSegmento->getX()){

                        d=((_inicioSegmento->getX() - _finSegmento->getX())
                                /(_finSegmento->getY() - _inicioSegmento->getY()))
                                        *(_finSegmento->getY() - wt);
                        _finSegmento->mueve(_finSegmento->getX()+d,wt);
                }else{
                        d=((_finSegmento->getX() - _inicioSegmento->getX())
                                /(_finSegmento->getY() - _inicioSegmento->getY()))
                                        *(_finSegmento->getY() - wt);
                        _finSegmento->mueve(_finSegmento->getX()-d,wt);
                }*/
                d=((_inicioSegmento->getX() - _finSegmento->getX())
                                /(_finSegmento->getY() - _inicioSegmento->getY()))
                                        *(_finSegmento->getY() - wt);
                _finSegmento->mueve(_finSegmento->getX()+d,wt);
        }
        //Frontera Derecha
        if(codP1==6 || codP1==2 || codP1==3 ){
                d=((_inicioSegmento->getY() - _finSegmento->getY())
                        /(_inicioSegmento->getX() - _finSegmento->getX()))
                                *(_inicioSegmento->getX() - wr);
                _inicioSegmento->mueve(wr,_inicioSegmento->getY()-d);
        }
        if(codP2==6 || codP2==2 || codP2==3 ){
                d=((_finSegmento->getY() - _inicioSegmento->getY())
                        /(_finSegmento->getX() - _inicioSegmento->getX()))
                                *(_finSegmento->getX() - wr);
                _finSegmento->mueve(wr,_finSegmento->getY()-d);
        }
        //Frontera Abajo
        if(codP1==9 || codP1==1 || codP1==3){
                d=((_finSegmento->getX() - _inicioSegmento->getX())
                        /(_finSegmento->getY() - _inicioSegmento->getY()))
                                *(wb - _inicioSegmento->getY());
                _inicioSegmento->mueve(_inicioSegmento->getX()+d,wb);
        }
        if(codP2==9 || codP2==1 || codP2==3){
                d=((_finSegmento->getX() - _inicioSegmento->getX())
                        /(_inicioSegmento->getY() - _finSegmento->getY()))
                                *(wb - _finSegmento->getY());
                _finSegmento->mueve(_finSegmento->getX()-d, wb);
        }
        return true;
}
//---------------------------------------------------------------------------
#pragma package(smart_init)
